package cn.lg.soar.mvc.log;

import cn.lg.soar.common.model.LogDTO;
import cn.lg.soar.common.util.IpUtil;
import cn.lg.soar.common.util.current.ICurrentUser;
import cn.lg.soar.common.util.current.UserContext;
import cn.lg.soar.common.util.data.StringUtil;
import cn.lg.soar.mvc.util.ServletUtils;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;

/**
 * 日志处理器
 * @author luguoxiang
 * @date 2022/4/23
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public interface ILogHandler {

    /**
     * 异步操作日志（异步保存，独立线程处理）
     * @param operate 操作
     * @param data 操作数据
     * @param dataId 操作数据的id
     * @param dataType 数据类型（比如表名、类名等）
     */
    void log(String operate, Object data, String dataId, String dataType);

    /**
     * 同步操作日志（同步保存，占用业务线程）
     * @param operate 操作
     * @param data 操作数据
     * @param dataId 操作数据的id
     * @param dataType 数据类型（比如表名、类名等）
     */
    void logSync(String operate, Object data, String dataId, String dataType);

    /**
     * 异步操作日志（异步保存，独立线程处理）
     * @param operate 操作
     * @param data 操作数据
     * @param dataId 操作数据的id
     */
    default void log(String operate, Object data, String dataId) {
        log(operate, data, dataId, null);
    }

    /**
     * 异步操作日志（异步保存，独立线程处理）
     * @param operate 操作
     * @param data 日志内容
     */
    default void log(String operate, Object data) {
        log(operate, data, null, null);
    }

    /**
     * 异步操作日志（异步保存，独立线程处理）
     * @param operate 操作
     */
    default void log(String operate) {
        log(operate, null, null, null);
    }


    /**
     * 同步操作日志（同步保存，占用业务线程）
     * @param operate 操作
     * @param data 操作数据
     * @param dataId 操作数据的id
     */
    default void logSync(String operate, Object data, String dataId) {
        logSync(operate, data, dataId, null);
    }

    /**
     * 同步操作日志（同步保存，占用业务线程）
     * @param operate 操作
     * @param data 日志内容
     */
    default void logSync(String operate, Object data) {
        logSync(operate, data, null, null);
    }

    /**
     * 同步操作日志（同步保存，占用业务线程）
     * @param operate 操作
     */
    default void logSync(String operate) {
        logSync(operate, null, null, null);
    }

    /**
     * 获取
     * @param operate
     * @param data
     * @param dataId
     * @return
     */
    static LogDTO getLogDTO(String operate, Object data, String dataId, String dataType) {
        HttpServletRequest request = ServletUtils.getRequest();
        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
        OperatingSystem operatingSystem = userAgent.getOperatingSystem();

        LogDTO dto = new LogDTO();

        ICurrentUser user = UserContext.getUserOrDef();
        dto.setTenantId(user.getCurrentTenantId(0));
        dto.setUserId(user.getId(0L));

        dto.setUserIp(IpUtil.getRemoteIp(request));
        dto.setDatetime(LocalDateTime.now());
        dto.setOperate(operate);
        dto.setDeviceType(operatingSystem.getDeviceType());
        dto.setPath(request.getMethod() + request.getServletPath());
        dto.setSystem(operatingSystem.getName());
        dto.setBrowser(userAgent.getBrowser().getName());
        dto.setData(data);

        if (!StringUtil.isBlank(dataId)) {
            dto.setDataId(dataId);
            if (StringUtil.isBlank(dataType)) {
                dto.setDataType(data.getClass().getName());
            } else {
                dto.setDataType(dataType);
            }
        }

        return dto;
    }
}
